package com.wonders.framework.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.PropertyUtils;

import com.wonders.framework.exception.FrameworkException;

/**
 * 校验工具
 * 
 * @author WuBin
 * 
 */
public class ValidateUtil {

	/**
	 * 空值校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean nullCheck(Object value) {
		if (value == null) {
			return false;
		}
		if (value instanceof String) {
			if (String.valueOf(value).length() < 1) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 空值校验
	 * 
	 * @param bean
	 *            对象
	 * @param properties
	 *            属性
	 * @return 是否通过校验
	 */
	public static boolean nullCheck(Object bean, String... properties) {
		if (bean == null) {
			return false;
		}
		if (properties == null) {
			return true;
		}
		for (String property : properties) {
			try {
				Object value = PropertyUtils.getProperty(bean, property);
				if (value == null) {
					return false;
				}
				Class type = PropertyUtils.getPropertyType(bean, property);
				if (String.class.equals(type)) {
					if (String.valueOf(value).length() < 1) {
						return false;
					}
				}
			} catch (Exception e) {
				throw new FrameworkException("校验参数时失败", e);
			}
		}
		return true;
	}

	/**
	 * 长度校验
	 * 
	 * @param value
	 *            值
	 * @param minLength
	 *            最小长度
	 * @param maxLength
	 *            最大长度
	 * @return 是否通过校验
	 */
	public static boolean lengthCheck(Object value, int minLength, int maxLength) {
		if (minLengthCheck(value, minLength)
				&& maxLengthCheck(value, maxLength)) {
			return true;
		}
		return false;
	}

	/**
	 * 最大长度校验
	 * 
	 * @param value
	 *            值
	 * @param maxLength
	 *            最大长度
	 * @return 是否通过校验
	 */
	public static boolean maxLengthCheck(Object value, int maxLength) {
		if (value == null) {
			return true;
		}
		String strValue = String.valueOf(value);
		if (strValue.length() <= maxLength) {
			return true;
		}
		return false;
	}

	/**
	 * 最小长度校验
	 * 
	 * @param value
	 *            值
	 * @param minLength
	 *            最小长度
	 * @return 是否通过校验
	 */
	public static boolean minLengthCheck(Object value, int minLength) {
		if (value == null) {
			if (minLength > 0) {
				return false;
			} else {
				return true;
			}
		}
		String strValue = String.valueOf(value);
		if (strValue.length() >= minLength) {
			return true;
		}
		return false;
	}

	/**
	 * 正则校验
	 * 
	 * @param value
	 *            值
	 * @param regex
	 *            正则
	 * @return 是否通过校验
	 */
	public static boolean regexCheck(String value, String regex) {
		if (value == null) {
			return false;
		}
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(value);
		return matcher.matches();
	}

	/**
	 * 手机号校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isCellPhone(String value) {
		return regexCheck(value, "^[1][34578][0-9]{9}$");
	}

	/**
	 * 固定电话校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isTelePhone(String value) {
		return regexCheck(value, "^(\\d{3}|\\d{4})-\\d{8}$");
	}

	/**
	 * 中文校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isChinese(String value) {
		return regexCheck(value, "^[\u4e00-\u9fa5]+$");
	}

	/**
	 * 字母、数字或下划线校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isLetterAndNumber(String value) {
		return regexCheck(value, "^[0-9a-zA-Z\\_]+$");
	}

	/**
	 * 邮箱校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isEmail(String value) {
		return regexCheck(
				value,
				"^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$");
	}

	/**
	 * URL校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isUrl(String value) {
		return regexCheck(value, "^((https|http|ftp|rtsp|mms)?://)"
				+ "?(([0-9a-z_!~*'().&=+$%-]+:)?[0-9a-z_!~*'().&=+$%-]+@)?"
				+ "(([0-9]{1,3}.){3}[0-9]{1,3}" + "|" + "([0-9a-z_!~*'()-]+.)*"
				+ "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]." + "[a-z]{2,6})"
				+ "(:[0-9]{1,5})?" + "((/?)|"
				+ "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$");
	}

	/**
	 * 正整数校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isNumber(Object value) {
		String strValue = String.valueOf(value);
		return regexCheck(strValue, "^[0-9]+");
	}

	/**
	 * 日期校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isDate(String value) {
		if (value == null || value.length() != 8) {
			return false;
		}
		int year = Integer.valueOf(value.substring(0, 4));
		int month = Integer.valueOf(value.substring(4, 6));
		int day = Integer.valueOf(value.substring(6, 8));
		if (year < 1950
				|| year > Integer.valueOf(DateUtil.toChar().substring(0, 4))) {
			return false;
		}
		if (month < 1 || month > 12) {
			return false;
		}
		int maxDay = DateUtil.getDays(year, month);
		if (day < 0 || day > maxDay) {
			return false;
		}
		return true;
	}

	/**
	 * 身份证校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isIdCard(String value) {
		if (value == null || value.length() != 18) {
			return false;
		}
		String[] valCodeArr = { "1", "0", "X", "9", "8", "7", "6", "5", "4",
				"3", "2" };
		String[] wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7",
				"9", "10", "5", "8", "4", "2" };
		String ai = value.substring(0, 17);
		if (!isNumber(ai)) {
			return false;
		}
		if (!isDate(ai.substring(6, 14))) {
			return false;
		}
		if (!regexCheck(ai.substring(0, 2),
				"^1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|71|8[1-2]|91")) {
			return false;
		}
		int totalmulAiWi = 0;
		for (int i = 0; i < 17; i++) {
			totalmulAiWi = totalmulAiWi
					+ Integer.parseInt(String.valueOf(ai.charAt(i)))
					* Integer.parseInt(wi[i]);
		}
		int modValue = totalmulAiWi % 11;
		String strVerifyCode = valCodeArr[modValue];
		ai = ai + strVerifyCode;
		return ai.equals(value);
	}

	/**
	 * 组织机构代码校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isOrganCode(String value) {
		if (value == null || value.length() != 9) {
			return false;
		}
		int[] ws = { 3, 7, 9, 10, 5, 8, 4, 2 };
		String str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		if (!regexCheck(value, "^([0-9A-Z]){8}-[0-9|X]$")) {
			return false;
		}
		value = value.replace("-", "");
		int sum = 0;
		for (int i = 0; i < 8; i++) {
			sum += str.indexOf(String.valueOf(value.charAt(i))) * ws[i];
		}
		int c9 = 11 - (sum % 11);
		String sc9 = String.valueOf(c9);
		if (11 == c9) {
			sc9 = "0";
		} else if (10 == c9) {
			sc9 = "X";
		}
		return sc9.equals(String.valueOf(value.charAt(8)));
	}

	/**
	 * 社会信用代码校验
	 * 
	 * @param value
	 *            值
	 * @return 是否通过校验
	 */
	public static boolean isSocialCreditCode(String value) {
		if (value == null || value.length() != 16) {
			return false;
		}
		int[] ws = { 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
				30, 28 };
		String str = "0123456789ABCDEFGHJKLMNPQRTUWXY";
		if (!regexCheck(value,
				"^[1|5|9|Y][1-3|9][0-9]{6}[0-9A-H|J-N|P-R|T|U|W-Y]{10}$")) {
			return false;
		}
		if (!regexCheck(value.substring(2, 4),
				"^1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|71|8[1-2]")) {
			return false;
		}
		if (!isOrganCode(value.substring(8, 16) + "-" + value.substring(16, 17))) {
			return false;
		}
		int sum = 0;
		for (int i = 0; i < 17; i++) {
			sum += str.indexOf(String.valueOf(value.charAt(i))) * ws[i];
		}
		int c18 = 31 - (sum % 31);
		if (c18 == 31) {
			c18 = 0;
		}
		return value.substring(17, 18).equals(String.valueOf(str.charAt(c18)));
	}

}
